﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;


namespace L9SubSet
{
	public enum LoadSubState
	{
		LoadSub_Default,
		LoadSub_FileError,
		LoadSub_NoExist,
		LoadSub_SolutionL9,
	};

	public class RVCardL9Config
	{
		private LoadSubState loadSubState = LoadSubState.LoadSub_Default;
		public ZQConfig zqConfig = new ZQConfig();

		public List<byte> loadSubData;			// 从 sub 文件中读取的数据

		#region 通用参数定义

		public int chipType;					// 芯片类型
		public int channel;						// 每颗芯片通道数
		public int packetLen;					// 每颗芯片数据包长度
		public int unitChipNum;					// 每单元芯片数
		public int unitPixelWidth;				// 每单元像素宽度
		public int unitPixelHight;				// 每单元像素高度
		public int doubleSpeed;					// 是否双倍数据传输速度：1-是，0-否
		public int columnMapReverse;			// 列映射表是否逆序：1-是，0-否
		public int dataEffect;					// 数据有效：0-屏蔽设置，1-data低有效，2-data高有效
		public int oeEffect;					// OE有效：0-屏蔽设置，1-data低有效，2-data高有效
		public int maxPixelLength;				// 最大带载点数
		public int pixelLength;					// 实际带载点数
		public double clockDuty;				// 占空比
		public int grayLevelIndex;				// 灰度等级
		public int syncMode;					// 同步刷新模式：0-关闭，1-开启
		public double gamma;					// Gamma值
		public int lowGraySmooth;				// 低灰平滑度
		public int startGray;					// 起灰值
		public int noSignalMode;				// 无信号显示时的模式：0-黑屏，1-最后一幅画面，2-自定义，3-测试动画
		public int clockFreqIndex;				// 时钟频率索引
		public int rgbwOrder;					// 颜色顺序：0-RGB，1-RBG，2-BGR，3-BRG，4-GRB，5-GBR
		public int sysControlMode;				// 显示性能控制：0-DVI控制，1-网口控制
		public bool alienEnable;				// 使能异形
		public int powerOnProtect;				// 开机渐亮保护
		public int persistCP;					// 保持屏体连接和调光调色参数
		public int colorOrderMode;				// 颜色顺序选择：0-规则排列，1-任意排列
		public int[] dxfData;					// 异形文件参数：0-水平点数，1-垂直点数，2-分控数量，3-灯具数量
		public int netDeviceIndex;				// 选择网卡的index
		public int chipColorModeCount;			// 芯片颜色总数：1-只有一种颜色模式，2-有两种颜色模式
		public int useChipNum;					// 芯片使用个数
        public int outInvert;				    // 输出反向：0-正常，1-反向
		public int fourColorMode;				// 四色模式选择：0-禁用，1-高亮纯模式，2-高亮增强模式，3-简单模式
		public int subNo;						// 该芯片在 FPGA 编号下方的子编号，与 FPGA 编号共同决定芯片编号
		public int channel4Color;				// 四色模式下的通道数
		public int currentAdjustEnable;			// 电流调节使能
		public int currentAdjustSpecial;		// 电流调节是否特殊处理
		public int currentChannelMax;			// 电流调节通道数
		public int currentLevelMax;				// 电流调节级数
		public int currentLevelDefault;			// 电流调节默认级数
		public int receiveCardWidth;			// 扩展接收卡截取宽度标志
		public int colorReverse;				// 色彩还原功能开关
		public int channelBrightEnable;			// 通道亮度调节使能
		public int brightR;						// 通道亮度-R
		public int brightG;						// 通道亮度-G
		public int brightB;						// 通道亮度-B
		public int brightW;						// 通道亮度-W

		// 0x413c-0x41ff 保留

		public List<byte> manualColorList;		// 自定义颜色顺序
		public string netDeviceName;			// 网卡名字
		public string noSignalPicFileName;		// 无信号显示时指定画面的图片文件路径（暂未使用） 
		public string dxfFileName;				// 异形文件路径
		public List<int> currentIndexList;		// 电流调节各通道index值

		#endregion

		#region Bin区专用参数定义

		public int blankGrayBin;				// 芯片空脚显示的灰度值
		public int curveMode;					// 曲线模式
		
		private List<int> grayCurveBin;			// 正常灰度曲线
		private List<int> grayCurveBin_2;		// Gamma=2的灰度曲线
		private List<int> grayCurveRatioBin;	// 正常灰度曲线与Gamma=2的灰度曲线的比值

		public int[] autoCurveTable = new int[256];
		public int[] autoCurveTable_2 = new int[256];
		public int[] autoCurveRatio = new int[256];
		public int[] manualCurveTable = new int[256];

		#endregion

		#region 内部参数定义

		public int mainColorMode;				// 选择的颜色模式
		public List<int> grayLevelList;			// 灰度等级列表
		public List<double> clockFreqList;		// 时钟频率列表
		public bool grayIndexChangedFlag;		// 判断灰度等级是否是从 sub 文件中读取的原始值，false-原始值，true-更改后的值

		public List<int> colorNumList;

		public bool channelManualEnable = false;

		#endregion

		#region 暂未处理的变量

		public int pixelMode;				// 芯片颜色
		public int minOE;
		public int scanFreqGray;
		public double disFreq;
		public double efficiency;
		public int contrast;				// 对比度

		#endregion

		// 构造函数
		public RVCardL9Config()
		{
			InitDefault();
			grayIndexChangedFlag = true;
		}

		// 初始化默认数据
		public void InitDefault()
		{
			#region 通用参数初始化

			chipType = 5;			// 默认的芯片为DMX512
			channel = 3;
			packetLen = 36;
			unitChipNum = 1;
			unitPixelWidth = 1;
			unitPixelHight = 1;
			doubleSpeed = 0;
			columnMapReverse = 0;
			oeEffect = 0;
			dataEffect = 0;
			maxPixelLength = 896;
			pixelLength = 128;
			clockDuty = 0.5;
			grayLevelIndex = 0;
			syncMode = 0;
			gamma = 1;
			lowGraySmooth = 0;
			startGray = 1;
			noSignalMode = 1;
            outInvert = 0;
            clockFreqIndex = 0;
			rgbwOrder = 0;			// 颜色顺序
			sysControlMode = 1;		// 0:DVI控制,1:网口控制
			alienEnable = false;
			powerOnProtect = 1;
			persistCP = 0;
			colorOrderMode = 0;
			dxfData = new int[4];
			netDeviceIndex = 0;
			chipColorModeCount = 2;
			useChipNum = 1;
			fourColorMode = 0;
			subNo = 0;
			channel4Color = 4;
			currentAdjustEnable = 0;
			currentAdjustSpecial = 0;
			currentChannelMax = 3;
			currentLevelDefault = 0;
			receiveCardWidth = 0;
			colorReverse = 0;
			channelBrightEnable = 1;
			brightR = 255;
			brightG = 255;
			brightB = 255;
			brightW = 255;

			// 0x413c-0x41ff 保留

			manualColorList = new List<byte>(512);
			for (int i = 0; i < 512; i++)
			{
				manualColorList.Add(0xff);
			}

			netDeviceName = "";
			noSignalPicFileName = "";
			dxfFileName = "";
			currentIndexList = new List<int>(4);
			for (int i = 0; i < currentChannelMax; i++)
			{
				currentIndexList.Add(currentLevelDefault);
			}

			// 根据管脚数量初始化颜色排列设置
			//if (channel == 3 || channel == 6 || channel == 9 || channel == 12)
			//{
			//    mainColorMode = 3;
			//    SetColorOrder(3, 0);	// 三色模式 - RGB
			//}
			//if (channel == 4 || channel == 8 || channel == 16)
			//{
			//    mainColorMode = 4;
			//    fourColorMode = 1;
			//    SetColorOrder(4, 6);	// 四色模式 - RGBW
			//}

			#endregion

			#region Bin区专用参数初始化

			blankGrayBin = 0;
			curveMode = 0;
			grayCurveBin = new List<int>(512);
			grayCurveBin_2 = new List<int>(512);
			grayCurveRatioBin = new List<int>(512);

			#endregion

			#region 内部参数初始化

			// 选择的颜色模式：三色模式
			mainColorMode = 3;

			// 初始化灰度等级列表
			InitGrayLevelList();

			// 初始化时钟频率列表
			InitClockFreqList();

			// 计算缺省显示性能曲线
			CalcAutoCurve();

			#endregion

			#region 暂未处理的变量

			pixelMode = 3;		// 芯片颜色默认为3
			contrast = 65536;
			minOE = 40;
			scanFreqGray = 50;
			disFreq = 300;
			efficiency = 0.7;

			#endregion
		}

		// 初始化灰度等级列表
		private void InitGrayLevelList()
		{
			zqConfig.Attach(GetAppPath() + @"\conf\L9Chip.ini");

			int maxGrayLevel = zqConfig.GetParameterInt("DMX512", "grayLevelMax");
			int minGrayLevel = zqConfig.GetParameterInt("DMX512", "grayLevelMin");
			int grayLevel = zqConfig.GetParameterInt("DMX512", "graylevel");

			int grayLevelCount = maxGrayLevel - minGrayLevel + 1;
			grayLevelList = new List<int>();
			for (int i = 0; i < grayLevelCount; i++)
			{
				// 判断是否只有一个等级若只有一个等级则添加一个等级
				if (maxGrayLevel - minGrayLevel == 0)
				{
					int level = Convert.ToInt32(Math.Pow(Convert.ToDouble(2), Convert.ToDouble(maxGrayLevel)));
					grayLevelList.Add(level);
				}

				string levelStr = zqConfig.GetParameterString("DMX512", "grayLevelList" + i);
				if (levelStr.Equals(""))
				{
					continue;
				}
				else
				{
					int level = Convert.ToInt32(levelStr);
					grayLevelList.Add(Convert.ToInt32(Math.Pow(Convert.ToDouble(2), Convert.ToDouble(level))));
				}
			}
		}

		// 初始化时钟频率列表
		private void InitClockFreqList()
		{
			clockFreqList = new List<double>(20);
			clockFreqList.Clear();
			clockFreqList.Add(7.5);
			clockFreqList.Add(150 / 18.8);
			clockFreqList.Add(150 / 16.7);
			clockFreqList.Add(150 / 15.0);
			clockFreqList.Add(150 / 12.5);
			clockFreqList.Add(150 / 10.0);
			clockFreqList.Add(150 / 7.5);
			clockFreqList.Add(150 / 6.25);
			clockFreqList.Add(150 / 5);
			clockFreqList.Add(150 / 4);
			clockFreqList.Add(150 / 3);
			clockFreqList.Add(150 / 2);
			clockFreqList.Add(150 / 1);
			clockFreqList.Add(150 / 0.8);
			clockFreqList.Add(150 / 0.625);
			clockFreqList.Add(150 / 0.500);
			clockFreqList.Add(150 / 0.400);
			clockFreqList.Add(150 / 0.330);
			clockFreqList.Add(150 / 0.250);
			clockFreqList.Add(150 / 0.1);
		}

		// 从 sub 文件中读取数据
		public LoadSubState LoadFromSub(string subFileName)
		{
			loadSubState = LoadSubState.LoadSub_Default;

			if (zqConfig.IsFileExist(subFileName) == false)
			{
				return LoadSubState.LoadSub_NoExist;
			}

			FileStream fs = new FileStream(subFileName, FileMode.Open);
			if (fs.Length == 0)
			{
				return LoadSubState.LoadSub_NoExist;
			}

			int dataLength = (int)fs.Length;
			byte[] dataBuff = new byte[dataLength];
			fs.Read(dataBuff, 0, dataLength);
			fs.Close();

			if (dataBuff[0x21] == 0)
			{
				return LoadSubState.LoadSub_FileError;
			}
			else if (dataBuff[0x21] == 1)
			{
				return LoadSubState.LoadSub_FileError;
			}
			else if (dataBuff[0x21] == 3)
			{
				return LoadSubState.LoadSub_FileError;
			}

			// 读取数据
			if (loadSubData == null)
			{
				loadSubData = new List<byte>(Convert.ToInt32(dataBuff.Length));
			}
			loadSubData.Clear();
			for (int i = 0; i < dataLength; i++)
			{
				loadSubData.Add(dataBuff[i]);
			}

			// 解析数据
			chipType = loadSubData[0x4100] * 256 + loadSubData[0x4101];
			switch (loadSubData[0x4102])
			{
				case 0:
					channel = 3;
					break;
				case 1:
					channel = 6;
					break;
				case 2:
					channel = 8;
					break;
				case 3:
					channel = 12;
					break;
				case 4:
					channel = 16;
					break;
				case 5:
					channel = 4;
					break;
				case 6:
					channel = 9;
					break;
				default:
					channel = 3;
					break;
			}
			if (loadSubData[0x413c] == 0x1)
			{
				channelManualEnable = true;
				channel = loadSubData[0x413d];
			}

			packetLen = loadSubData[0x4103] * 256 + loadSubData[0x4104];
			unitChipNum = loadSubData[0x4105] * 256 + loadSubData[0x4106];
			unitPixelWidth = loadSubData[0x4107] * 256 + loadSubData[0x4108];
			unitPixelHight = loadSubData[0x4109] * 256 + loadSubData[0x410a];
			doubleSpeed = loadSubData[0x410b];
			columnMapReverse = loadSubData[0x410c];
			dataEffect = loadSubData[0x410d];
			oeEffect = loadSubData[0x410e];
			maxPixelLength = loadSubData[0x410f] * 256 + loadSubData[0x4110];
			pixelLength = loadSubData[0x4111] * 256 + loadSubData[0x4112];
			clockDuty = loadSubData[0x4113] / 100.0;
			grayLevelIndex = 16 - loadSubData[0x4114] / 3;
			grayIndexChangedFlag = false;
			syncMode = loadSubData[0x4115];
			gamma = ((loadSubData[0x4116] & 0x0f) + (loadSubData[0x4116] >> 4) * 0.1);
			lowGraySmooth = loadSubData[0x4117];
			startGray = loadSubData[0x4118];
			noSignalMode = loadSubData[0x4119];
			clockFreqIndex = loadSubData[0x411a];
			rgbwOrder = loadSubData[0x411b];
			//sysControlMode = loadSubData[0x411c];
			sysControlMode = 1;     // iBluePlayer只支持使用网口模式，防止使用老Sub时配置错误
			alienEnable = Convert.ToBoolean(loadSubData[0x411d]);
			powerOnProtect = loadSubData[0x411e];
			persistCP = loadSubData[0x411f];
			colorOrderMode = loadSubData[0x4120];
			dxfData[0] = loadSubData[0x4121] * 256 + loadSubData[0x4122];
			dxfData[1] = loadSubData[0x4123] * 256 + loadSubData[0x4124];
			dxfData[2] = loadSubData[0x4125] * 256 + loadSubData[0x4126];
			dxfData[3] = loadSubData[0x4127] * 256 + loadSubData[0x4128];
			netDeviceIndex = loadSubData[0x4129];
			chipColorModeCount = loadSubData[0x412a];
			SetSelectedChipMode(loadSubData[0x412b]);
			useChipNum = loadSubData[0x412c];
			fourColorMode = loadSubData[0x412d];
			subNo = loadSubData[0x412e];
			channel4Color = loadSubData[0x4130] == 0 ? 4 : loadSubData[0x4130];
			currentAdjustEnable = loadSubData[0x4131];
			currentAdjustSpecial = loadSubData[0x4132];
			currentChannelMax = loadSubData[0x4133];
			currentLevelMax = loadSubData[0x4134];
			receiveCardWidth = loadSubData[0x4135];
			colorReverse = loadSubData[0x4136];
			channelBrightEnable = loadSubData[0x4137];
            outInvert = loadSubData[0x413e];

			brightR = loadSubData[0x7000];	// 应同时存入0x4138
			brightG = loadSubData[0x7001];	// 应同时存入0x4139
			brightB = loadSubData[0x7002];	// 应同时存入0x413a
			brightW = loadSubData[0x7003];	// 应同时存入0x413b

			// 读取自定义颜色顺序
			for (int i = 0; i < 512; i++)
			{
				manualColorList[i] = loadSubData[0x4200 + i];
			}

			// 读取网卡名字
			char[] netDeviceNameChars = new char[256];
			Bytes2Chars(loadSubData, 0x5000, netDeviceNameChars.Length, netDeviceNameChars);
			netDeviceName = new string(netDeviceNameChars);

			// 读取异形文件路径
			char[] dxfFile = new char[1024];
			Bytes2Chars(loadSubData, 0x5400, dxfFile.Length, dxfFile);
			dxfFileName = new string(dxfFile);
			loadSubState = LoadSubState.LoadSub_SolutionL9;
			
			// 读取电流调节通道的电流值
			currentIndexList.Clear();
			int currentAddr = 0x5800;
			for (int i = 0; i < currentChannelMax; i++)
			{
				currentIndexList.Add(loadSubData[currentAddr + i]);
			}

			// 计算缺省显示性能曲线
			CalcAutoCurve();

			return loadSubState;
		}

		// 生成 sub 数据
		public byte[] GetSubData()
		{
			GenL9SubData(loadSubData);

			int dataSize = loadSubData.Count;
			byte[] binBuff = new byte[dataSize];
			for (int i = 0; i < dataSize; i++)
			{
				binBuff[i] = loadSubData[i];
			}

			return binBuff;
		}

		// 生成 sub 数据（L9）
		private void GenL9SubData(List<byte> binBuffData)
		{
			byte[] binBuff = null;
			if (binBuffData != null)
			{
				binBuff = binBuffData.ToArray();
			}
			else
			{
				binBuff = new byte[128 * 1024];
			}

			if (loadSubData == null)
			{
				loadSubData = new List<byte>(0x20000);
				for (int i = 0; i < 0x20000; i++)
				{
					loadSubData.Add(0);
				}
			}

			// 计算灰度曲线
			GenGrayCurveBin();

			for (int i = 0; i < 0x20000; i++)
			{
				binBuff[i] = 0;
			}

			binBuff[0x004] = 8;		// DLL 版本 0x080200
			binBuff[0x005] = 2;
			binBuff[0x006] = 0;
			binBuff[0x008] = 0x00;	// 0x00010000
			binBuff[0x009] = 0x00;
			binBuff[0x00a] = 0x01;
			binBuff[0x00b] = 0x00;
			binBuff[0x00c] = 0x00;	// 0x00010000
			binBuff[0x00d] = 0x00;
			binBuff[0x00e] = 0x01;
			binBuff[0x00f] = 0x00;
			binBuff[0x021] = 0x02;	// L9
			binBuff[0x022] = 0x08;	// 最小兼容版本
			binBuff[0x023] = 0x02;	//
			binBuff[0x024] = 0x00;	//

			// 配置区有效数据地址与数据长度对应关系
			// 【重要】要与 GenDownloadData 函数中各段下发的长度一致
			binBuff[0x080] = 0x00;	// addr:0x001000
			binBuff[0x081] = 0x10;
			binBuff[0x082] = 0x00;	// len: 256
			binBuff[0x083] = 0x01;

			binBuff[0x084] = 0x00;	// addr:0x003000
			binBuff[0x085] = 0x30;
			binBuff[0x086] = 0x00;	// len: 512
			binBuff[0x087] = 0x02;

			binBuff[0x088] = 0x00;	// addr:0x004000
			binBuff[0x089] = 0x40;
			binBuff[0x08a] = 0x00;	// len:	512
			binBuff[0x08b] = 0x02;

			binBuff[0x08c] = 0x00;	// addr:0x008000
			binBuff[0x08d] = 0x80;
			binBuff[0x08e] = 0x00;	// len:	256
			binBuff[0x08f] = 0x01;

			binBuff[0x4100] = Convert.ToByte(chipType >> 8);	// 芯片类型
			binBuff[0x4101] = Convert.ToByte(chipType);
			byte channelValue;
			switch (channel)
			{
				case 3:
					channelValue = 0;
					break;
				case 6:
					channelValue = 1;
					break;
				case 8:
					channelValue = 2;
					break;
				case 12:
					channelValue = 3;
					break;
				case 16:
					channelValue = 4;
					break;
				case 4:
					channelValue = 5;
					break;
				case 5:
					channelValue = 9;
					break;
				default:
					channelValue = 0;
					break;
			}
			binBuff[0x4102] = Convert.ToByte(channelValue);					// 每颗芯片通道数
			int channelFour = channel4Color == 0 ? 4 : channel4Color;
			binBuff[0x4103] = Convert.ToByte(packetLen >> 8);			// 每颗芯片数据包长度 - 高
			binBuff[0x4104] = Convert.ToByte(packetLen);				// 每颗芯片数据包长度 - 低
			binBuff[0x4105] = Convert.ToByte(unitChipNum >> 8);			// 每单元芯片数 - 高
			binBuff[0x4106] = Convert.ToByte(unitChipNum);				// 每单元芯片数 - 低
			binBuff[0x4107] = Convert.ToByte(unitPixelWidth >> 8);		// 每单元像素宽度 - 高
			binBuff[0x4108] = Convert.ToByte(unitPixelWidth);			// 每单元像素宽度 - 低
			binBuff[0x4109] = Convert.ToByte(unitPixelHight >> 8);		// 每单元像素高度 - 高
			binBuff[0x410a] = Convert.ToByte(unitPixelHight);			// 每单元像素高度 - 低
			binBuff[0x410b] = Convert.ToByte(doubleSpeed);				// 是否是双倍数据传输速度
			binBuff[0x410c] = Convert.ToByte(columnMapReverse);			// 列映射表是否逆序
			binBuff[0x410d] = Convert.ToByte(dataEffect);				// 数据有效
			binBuff[0x410e] = Convert.ToByte(oeEffect);					// OE有效
			binBuff[0x410f] = Convert.ToByte(maxPixelLength >> 8);		// 最大带载点数 - 高
			binBuff[0x4110] = Convert.ToByte(maxPixelLength % 256);		// 最大带载点数 - 低
			binBuff[0x4111] = Convert.ToByte(pixelLength >> 8);			// 实际带载点数 - 高
			binBuff[0x4112] = Convert.ToByte(pixelLength % 256);		// 实际带载点数 - 低
			binBuff[0x4113] = Convert.ToByte(clockDuty * 100);			// 占空比
			int grayleve = 0;
			while (Math.Pow(2, grayleve) != grayLevelList[grayLevelIndex])
			{
				grayleve++;
			}
			binBuff[0x4114] = Convert.ToByte((16 - grayleve) * 3);		// 灰度等级
			binBuff[0x4115] = Convert.ToByte(0);						// 同步刷新模式，设置默认关闭（0）
			binBuff[0x4116] = Convert.ToByte(Math.Floor(gamma) + Math.Floor((gamma - Math.Floor(gamma)) * 10 + 0.5) * 16);	// Gamma值
			binBuff[0x4117] = Convert.ToByte(lowGraySmooth);			// 低灰平滑度
			binBuff[0x4118] = Convert.ToByte(startGray);				// 起灰值
			binBuff[0x4119] = Convert.ToByte(noSignalMode);				// 无信号显示（这里先默认为零）
			binBuff[0x411a] = Convert.ToByte(clockFreqIndex);			// 时钟频率
			binBuff[0x411b] = Convert.ToByte(rgbwOrder);				// 颜色顺序
			binBuff[0x411c] = Convert.ToByte(sysControlMode);			// 显示性能控制
			binBuff[0x411d] = Convert.ToByte(alienEnable);				// 使能异形
			binBuff[0x411e] = Convert.ToByte(powerOnProtect);			// 开机渐亮保护
			binBuff[0x411f] = Convert.ToByte(persistCP);				// 保持屏体连接和调光调色参数
			binBuff[0x4120] = Convert.ToByte(colorOrderMode);			// 颜色顺序选择：0-规则排列，1-任意排列

            // 根据列映射表给 bin 赋值
            for (int i = 0; i < 512; i++)
            {
                binBuff[0x4200 + i] = manualColorList[i];
                if (manualColorList[i] == 0xff)
                {
                    binBuff[0x13000 + i] = 0x0;
                }
                else
                {
                    binBuff[0x13000 + i] = manualColorList[i];
                }
            }
            
            // 计算每灯具像素数
            if (colorOrderMode == 0)
			{
				binBuff[0x11020] = Convert.ToByte((unitChipNum * channel) / 3 - 1);		//自动排列时，按通道数除3计算（三色模式）
			}
			else // 任意排列
			{
				int pix = GetChipPixelMaxAndMin();
                binBuff[0x11020] = Convert.ToByte(pix);
			}
			binBuff[0x4121] = Convert.ToByte(dxfData[0] << 8);
			binBuff[0x4122] = Convert.ToByte(dxfData[0] & 0xFF);
			binBuff[0x4123] = Convert.ToByte(dxfData[1] << 8);
			binBuff[0x4124] = Convert.ToByte(dxfData[1] & 0xFF);
			binBuff[0x4125] = Convert.ToByte(dxfData[2] << 8);
			binBuff[0x4126] = Convert.ToByte(dxfData[2] & 0xFF);
			binBuff[0x4127] = Convert.ToByte(dxfData[3] >> 8);
			binBuff[0x4128] = Convert.ToByte(dxfData[3] & 0xFF);
			binBuff[0x4129] = Convert.ToByte(netDeviceIndex);
			binBuff[0x412a] = Convert.ToByte(chipColorModeCount);
			binBuff[0x412b] = Convert.ToByte(mainColorMode);
			binBuff[0x412c] = Convert.ToByte(useChipNum);
			binBuff[0x412d] = Convert.ToByte(fourColorMode);
			binBuff[0x412e] = Convert.ToByte(subNo);
			binBuff[0x4130] = Convert.ToByte(channelFour);				// 4色模式下的通道数
			binBuff[0x4131] = Convert.ToByte(currentAdjustEnable);		// 电流调节使能
			binBuff[0x4132] = Convert.ToByte(currentAdjustSpecial);		// 电流调节是否特殊处理
			binBuff[0x4133] = Convert.ToByte(currentChannelMax);		// 电流调节通道数
			binBuff[0x4134] = Convert.ToByte(currentLevelMax);			// 电流调节级数
			binBuff[0x4135] = Convert.ToByte(receiveCardWidth);			// 扩展接收卡截取宽度标志
			binBuff[0x4136] = Convert.ToByte(colorReverse);				// 色彩还原功能开关
			binBuff[0x4137] = Convert.ToByte(channelBrightEnable);		// 通道亮度调节使能
			binBuff[0x4138] = Convert.ToByte(brightR);					// 通道亮度-R
			binBuff[0x4139] = Convert.ToByte(brightG);					// 通道亮度-G
			binBuff[0x413a] = Convert.ToByte(brightB);					// 通道亮度-B
			binBuff[0x413b] = Convert.ToByte(brightW);					// 通道亮度-W
			
			// 支持手动修改芯片通道数
			if (channelManualEnable == true)
			{
				binBuff[0x4102] = 0x0;									// 停用0x4102字节
				binBuff[0x413c] = 0x1;									// 手动芯片通道数使能
				channelValue = (byte)channel;							// 手动芯片通道数
				binBuff[0x413d] = Convert.ToByte(channelValue);			
			}
            binBuff[0x413e] = Convert.ToByte(outInvert);			    // 输出反向：0-正常，1-反向

			// 保存网卡名字
			if (netDeviceName.Length > 0 && netDeviceName.Length < 256)
			{
				for (int i = 0; i < netDeviceName.Length; i++)
				{
					binBuff[0x5000 + i] = Convert.ToByte(netDeviceName[i]);
				}
			}
			// 保存异形文件路径
			if (dxfFileName.Length > 0 && dxfFileName.Length < 1024)
			{
				for (int i = 0; i < dxfFileName.Length; i++)
				{
					binBuff[0x5400 + i] = Convert.ToByte(dxfFileName[i]);
				}
			}

			/************************************************************************************/

			binBuff[0x10100] = 0;			// 分控在屏幕行方向上的截取起始位置, 低字节
			binBuff[0x10101] = 0;			// 分控在屏幕行方向上的截取起始位置, 高字节
			binBuff[0x10102] = 0;			// 分控在屏幕列方向上的截取起始位置, 低字节
			binBuff[0x10103] = 0;			// 分控在屏幕列方向上的截取起始位置, 高字节
			if (receiveCardWidth == 0)
			{
				binBuff[0x10104] = 0x80;	// 分控在屏幕行方向上的截取大小，低字节
				binBuff[0x10105] = 0x03;	// 分控在屏幕行方向上的截取大小，高字节
				binBuff[0x10106] = 0x80;	// 分控在屏幕列方向上的截取大小，低字节
				binBuff[0x10107] = 0x03;	// 分控在屏幕列方向上的截取大小，高字节

			}
			else if (receiveCardWidth == 1)
			{
				// 修改拓展显示时行列相反的BUG zhangjin 提供
				binBuff[0x10104] = 0x00;	// 分控在屏幕行方向上的截取大小，低字节
				binBuff[0x10105] = 0x02;	// 分控在屏幕行方向上的截取大小，高字节
				binBuff[0x10106] = 0x50;	// 分控在屏幕列方向上的截取大小，低字节
				binBuff[0x10107] = 0x05;	// 分控在屏幕列方向上的截取大小，高字节
			}
			binBuff[0x10108] = 1;			// 屏号，从 1 开始计数，0 保留。
			double clockData = clockFreqList[clockFreqIndex];
			int clk = Convert.ToInt32(clockFreqList[clockFreqIndex]);
			binBuff[0x11000] = Convert.ToByte(clk % 256);		// 时钟分频数n，表示out_clk=150M/n
			int clock_low_time = Convert.ToInt32(clockData * (1 - clockDuty) % 256);
			binBuff[0x11001] = Convert.ToByte(clock_low_time);	// 输出时钟低电平数/*(binBuf[0x11000]*(1-m_clkDuty))*/ 

			// 判断颜色模式
            //if (mainColorMode == 3)
            //{
            //    binBuff[0x11016] = Convert.ToByte((pixelLength * mainColorMode / (useChipNum * channel) - 1) % 256);
            //    binBuff[0x11017] = Convert.ToByte((pixelLength * mainColorMode / (useChipNum * channel) - 1) >> 8);
            //    binBuff[0x11018] = Convert.ToByte(useChipNum * channel - 1);
            //}
            //else if (mainColorMode == 4)
            //{
            //    binBuff[0x11016] = Convert.ToByte((pixelLength * mainColorMode / (useChipNum * channelFour) - 1) % 256);
            //    binBuff[0x11017] = Convert.ToByte((pixelLength * mainColorMode / (useChipNum * channelFour) - 1) >> 8);
            //    binBuff[0x11018] = Convert.ToByte(useChipNum * channelFour - 1);
            //}

            binBuff[0x11016] = Convert.ToByte((pixelLength - 1) % 256); // 每输出口的带载灯条数-1，低字节
            binBuff[0x11017] = Convert.ToByte((pixelLength - 1) >> 8);  // 每输出口的带载灯条数-1，高字节
            binBuff[0x11018] = 2;                                       // 每根灯条的通道数-1,默认为3通道灯

			// 四色模式值
            binBuff[0x1109c] = 0;                                   // 四色模式不再发送至分控
			binBuff[0x11050] = Convert.ToByte(noSignalMode);		// 无信号时显示状态, 0：黑屏, 非0：保持最后一帧画面

			binBuff[0x11080] = Convert.ToByte(clk >> 8);			// 时钟高电平分频数高8位
			binBuff[0x11081] = Convert.ToByte(clock_low_time >> 8);	// 时钟低电平分频数高8位
			binBuff[0x11082] = Convert.ToByte(chipType);			// 芯片类型
			binBuff[0x11083] = Convert.ToByte(blankGrayBin);		// 空脚显示的灰度值

			binBuff[0x11090] = 0x10;		// MY9221配置参数—典型值 (16bit PWM) 8’b 0001_0000
			binBuff[0x11091] = 0x03;		// MY9221配置参数—典型值 (16bit PWM) 8’b 0000_0011
			binBuff[0x11092] = 0x7f;		// TI5970配置参数—典型值 8’b 0111_1111
			binBuff[0x11093] = 0x09;		// TI5970配置参数—典型值 8’b 0000_1001

			int ic_num = ((pixelLength * 3) / channel) - 1;
			binBuff[0x11094] = Convert.ToByte(ic_num % 256);			// 级联的 6024/6020/MBI6021/MBI6030/Sm16716 芯片个数 - 1
			binBuff[0x11095] = Convert.ToByte(ic_num / 256);
			binBuff[0x11096] = Convert.ToByte((pixelLength - 1) % 256);	// 级联的像素点数，LPD6803/LPD8806也需要此配置值，且定义也是级联的像素点数
            binBuff[0x11097] = Convert.ToByte((pixelLength - 1) >> 8);
            binBuff[0x110a5] = Convert.ToByte(outInvert);               // 输出反向：0-正常，1-反向

			// 判断是DVI播放还是网口播放
			if (sysControlMode == 0)
			{
				binBuff[0x11099] = 0;
			}
			else
			{
				binBuff[0x11099] = 1;
			}

			for (int i = 0; i < grayCurveBin.Count; i = i + 1)
			{
				binBuff[0x14000 + i] = Convert.ToByte(grayCurveBin[i]);
			}

			if (alienEnable == false || sysControlMode == 1)
			{
				// 异形非使能
				binBuff[0x18000] = 0x80;
			}
			else
			{
				// 异形使能, 将异形文件写入到sub文件里
				binBuff[0x18000] = 0;
			}

			// 电流调节使能
			if (currentAdjustEnable == 1)
			{
				// 前 64K 存储软件用
				for (int i = 0; i < 256; i++)
				{
					if (i < currentChannelMax)
					{
						binBuff[0x5800 + i] = Convert.ToByte(currentIndexList[i]);
					}
					else
					{
						binBuff[0x5800 + i] = 0;
					}
				}
				// 后 64K 存储下发至分控 bin 区
				if (currentLevelMax > 16)
				{
					for (int i = 0; i < 12; i++)
					{
						if (i < currentChannelMax)
						{
							binBuff[0x1109d + i] = Convert.ToByte(currentIndexList[i]);
						}
						else
						{
							binBuff[0x1109d + i] = 0;
						}
					}
				}
				else
				{
					for (int i = 0; i < 12; i = i + 1)
					{
						if (i < currentChannelMax / 2)
						{
							binBuff[0x1109d + i] = Convert.ToByte((currentIndexList[2 * i]) * 16 + currentIndexList[2 * i + 1]);
						}
						else
						{
							binBuff[0x1109d + i] = 0;
						}
					}
				}
			}

			// 色彩还原后64位存储
			binBuff[0x11032] = Convert.ToByte(colorReverse);	// 色彩还原模式
			binBuff[0x11033] = binBuff[0x4114];					// 灰度等级
			binBuff[0x11034] = binBuff[0x4116];					// Gamma值
			binBuff[0x11035] = binBuff[0x4118];					// 起灰值
			binBuff[0x11036] = binBuff[0x4117];					// 低灰平滑度

			// 色彩还原 0x004200~0x0043ff 存储
			for (int i = 0; i < grayCurveBin_2.Count; i++)
			{
				binBuff[0x14200 + i] = Convert.ToByte(grayCurveBin_2[i]);
			}
			// 色彩还原 0x004400~0x0045ff 存储
			for (int i = 0; i < grayCurveRatioBin.Count; i++)
			{
				binBuff[0x14400 + i] = Convert.ToByte(grayCurveRatioBin[i]);
			}

			// 通道亮度 - R/G/B/W
			binBuff[0x7000] = (byte)brightR;
			binBuff[0x7001] = (byte)brightG;
			binBuff[0x7002] = (byte)brightB;
			binBuff[0x7003] = (byte)brightW;
			binBuff[0x17000] = (byte)brightR;
			binBuff[0x17001] = (byte)brightG;
			binBuff[0x17002] = (byte)brightB;
			binBuff[0x17003] = (byte)brightW;

			// crc 校验
			//ulong crc = GetCRC32(binBuf, 0x20000 - 4);
			//binBuf[3] = Convert.ToByte(crc >> 24);
			//binBuf[2] = Convert.ToByte(crc%(Math.Pow(2, 8)));
			//binBuf[1] = Convert.ToByte(crc%(Math.Pow(2, 16)));
			//binBuf[0] = Convert.ToByte(crc%(Math.Pow(2,24)));

			loadSubData = binBuff.ToList();
		}

		// 保存 sub 文件
		public void SaveToSub(string subFileName, int subVersion)
		{
			FileStream fs = new FileStream(subFileName, FileMode.OpenOrCreate);
			BinaryWriter bw = new BinaryWriter(fs);

			GenL9SubData(loadSubData);

			int nDataSize = loadSubData.Count;
			byte[] saveBinBuff = new byte[nDataSize];
			for (int i = 0; i < nDataSize; i++)
			{
				saveBinBuff[i] = loadSubData[i];
			}

			bw.Write(saveBinBuff);
			bw.Close();
			fs.Close();
		}

		/**********************************************************************************/

		// 计算缺省显示性能曲线
		private void CalcAutoCurve()
		{
			int pwm_max;

			if (grayIndexChangedFlag == false)
			{
				pwm_max = Convert.ToInt32(Math.Pow(Convert.ToDouble(2), Convert.ToDouble(grayLevelIndex))) - 1;
			}
			else
			{
				pwm_max = grayLevelList[grayLevelIndex] - 1;
			}

			CalcCurve(pwm_max, gamma, startGray, lowGraySmooth, autoCurveTable);

			// add by xwwang 20150605 增加2的pwm表
			CalcCurve(pwm_max, 2, startGray, lowGraySmooth, autoCurveTable_2);

			for (int i = 0; i < 256; i++)
			{
				if (autoCurveTable_2[i] == 0)
				{
					autoCurveRatio[i] = 0;
				}
				else
				{
					autoCurveRatio[i] = ((autoCurveTable[i] * 256) / autoCurveTable_2[i]);
					if (autoCurveRatio[i] > 65535)
					{
						autoCurveRatio[i] = 65535;
					}
				}
			}
		}

		// 计算显示性能曲线
		private void CalcCurve(int contrastValue, double gammaValue, int startGrayValue, int kValue, int[] curveTable)
		{
			int i = 0, x = 0;
			int d_xt = 0, d_adj = 0, d_x0 = 0, d_line_adj = 0;
			double d_b = 0, d_k = 0, d_a0 = 0, d_b0 = 0;
			double f0_x = 0, f1_x = 0, ft_x = 0, f0_x0 = 0, f0d1_x0 = 0;
			double data_a = 0, data_b = 0;
			double[] f = new double[1024];

			// 准备标准曲线参数
			if (startGrayValue > 1)
			{
				d_b = startGrayValue - 1;
			}
			else
			{
				d_b = 0;
			}

			if (kValue > 0)
			{
				d_k = 1 / (double)kValue;
			}

			// 计算标准曲线
			for (x = startGrayValue; x <= 255; x++)
			{
				data_a = (x - d_b) / (255 - d_b);
				data_b = Math.Pow(data_a, gammaValue);
				f0_x = contrastValue * data_b;
				f[x] = f0_x;
			}

			// 计算调整范围
			if (kValue > 0)
			{
				// 计算直线和标准曲线交点
				for (x = startGrayValue; x <= 255; x++)
				{
					d_xt = x;
					f0_x = f[x];
					ft_x = d_k * (x - d_b);
					if (f0_x > ft_x)
					{
						break;
					}
				}
				// 调整范围
				d_line_adj = Convert.ToInt32(d_xt - d_b);
				if (d_line_adj > 32)
				{
					d_x0 = d_xt + 16;
				}
				else
				{
					d_x0 = d_xt + d_line_adj / 2;
				}
			}

			// 计算调整曲线参数
			if (kValue > 0)
			{
				for (i = 0; i < d_line_adj; i = i + 1)
				{
					d_adj = Convert.ToInt32(d_x0 - d_b - i);
					
					// 标准曲线结束点的值
					f0_x0 = f[d_x0] - i * d_k;
					
					// 标准曲线结束点的一阶倒数
					f0d1_x0 = f[d_x0] - f[d_x0 - 1];
					
					// 调整曲线的3次项和2次项系数
					d_a0 = (f0d1_x0 * d_adj + d_k * d_adj - 2 * f0_x0) / (d_adj * d_adj * d_adj);
					d_b0 = (3 * f0_x0 - 2 * d_k * d_adj - f0d1_x0 * d_adj) / (d_adj * d_adj);
					
					if (d_b0 > 0)
					{
						break;
					}
				}
				d_line_adj = i;
			}

			// 计算调整曲线
			if (kValue > 0)
			{
				for (x = startGrayValue; x < startGrayValue + d_line_adj; x++)
				{
					data_a = x - d_b;
					f1_x = data_a * d_k;
					f[x] = f1_x;
				}
				for (x = startGrayValue + d_line_adj; x < d_x0; x++)
				{
					data_a = x - d_b - d_line_adj;
					f1_x = d_a0 * data_a * data_a * data_a + d_b0 * data_a * data_a + d_k * data_a + d_line_adj * d_k;
					f[x] = f1_x;
				}
			}

			// 曲线整理
			for (i = 0; i <= 255; i++)
			{
				if (i < startGrayValue)
				{
					curveTable[i] = 0;
				}
				else
				{
					// 四舍五入
					curveTable[i] = Convert.ToInt32(Math.Floor(f[i] + 0.5));
					
					// 防止溢出
					if (curveTable[i] > contrastValue)
					{
						curveTable[i] = contrastValue;
					}
					if (curveTable[i] < 1)
					{
						curveTable[i] = 1;
					}
				}
			}
		}

		// 计算灰度曲线
		private void GenGrayCurveBin()
		{
			int addr = 0, i = 0;
			for (i = 0; i < 256; i = i + 1)
			{
				manualCurveTable[i] = loadSubData[0x300 + i * 4 + 3] * 256 + loadSubData[0x300 + i * 4 + 2];
			}

			if (grayCurveBin == null)
			{
				grayCurveBin = new List<int>(512);
			}
			if (grayCurveBin_2 == null)
			{
				grayCurveBin_2 = new List<int>(512);
			}
			if (grayCurveRatioBin == null)
			{
				grayCurveRatioBin = new List<int>(512);
			}

			grayCurveBin.Clear();
			grayCurveBin_2.Clear();
			grayCurveRatioBin.Clear();

			int temp = 0;
			for (i = 0; i < 256; i = i + 1)
			{
				addr = i * 2;

				if (curveMode == 0)
				{
					temp = Convert.ToInt32(Math.Floor(Convert.ToDouble(autoCurveTable[i]) / 256));
					grayCurveBin.Add(autoCurveTable[i] - temp * 256);
					grayCurveBin.Add(temp);
				}
				else
				{
					temp = Convert.ToInt32(Math.Floor(Convert.ToDouble(manualCurveTable[i]) / 256));
					grayCurveBin.Add(manualCurveTable[i] - temp * 256);
					grayCurveBin.Add(temp);
				}

				temp = Convert.ToInt32(Math.Floor(Convert.ToDouble(autoCurveTable_2[i]) / 256));
				grayCurveBin_2.Add(autoCurveTable_2[i] - temp * 256);
				grayCurveBin_2.Add(temp);

				temp = Convert.ToInt32(Math.Floor(Convert.ToDouble(autoCurveRatio[i]) / 256));
				grayCurveRatioBin.Add(autoCurveRatio[i] - temp * 256);
				grayCurveRatioBin.Add(temp);
			}
		}
		
		// 计算芯片最大、最小像素数
		private int GetChipPixelMaxAndMin()
		{
			int i, min, max, ddd;

			//最大、最小像素数初始化
			min = 0xFF;
			max = 0x00;

			//遍历列映射表，查找最大、最小像素数
			for (i = 0; i < 512; i = i + 2)
			{
				ddd = manualColorList[i];
				if (ddd < 0xFF)
				{
					if (ddd > max)
					{
						max = ddd;
					}
					if (ddd < min)
					{
						min = ddd;
					}
				}
			}

			if (min >= max)
			{
				return 0;
			}
			else
			{
				return max - min;
			}
		}

		#region Getter/Setter

		public int SetClockFreqList(List<double> li)
		{
			clockFreqList.Clear();
			for (int i = 0; i < li.Count; i++)
			{
				clockFreqList.Add(Convert.ToDouble(150 / li[i]));
			}
			return clockFreqIndex;
		}

		public int SetGrayLevelList(List<int> li)
		{
			grayLevelList.Clear();
			for (int i = 0; i < li.Count; i++)
			{
				grayLevelList.Add(li[i]);
			}
			return grayLevelIndex;
		}

		public void SetGrayIndex(int index)
		{
			if (grayLevelIndex == index)
			{
				return;
			}
			else
			{
				grayLevelIndex = index;
				grayIndexChangedFlag = true;
				CalcAutoCurve();
			}
		}

		public void SetGamma(double gamma)
		{
			this.gamma = gamma;
			CalcAutoCurve();
		}

		public void SetGrayStart(int startGrayValue)
		{
			startGray = startGrayValue;
			CalcAutoCurve();
		}

		public void SetLowGraySmooth(int lowGraySmoothValue)
		{
			lowGraySmooth = lowGraySmoothValue;
			CalcAutoCurve();
		}

		// 分控设置 - 灯具颜色排列
		public void colorOrderAutoCalculate(string chipName, string colorOrderString, int rgbwOrder)
		{
			//重置灯具芯片个数
			useChipNum = 1;

			//设置芯片通道数
			string chipDefaultChannle = zqConfig.GetParameterString(chipName, "channel");

			if (chipDefaultChannle.ToLower().Equals("manual"))
				channel = colorOrderString.Length;
			else
				channel = Convert.ToInt32(chipDefaultChannle);

			// 确定芯片颜色模式
			if (colorOrderString.Length == 3)
			{
				mainColorMode = 3;
				fourColorMode = 0;
			}
			else if (colorOrderString.Length == 4)
			{
				mainColorMode = 4;
				fourColorMode = 1;
			}

			// 填写 manualColorList
			SetColorOrder(mainColorMode, rgbwOrder);
		}

		public void SetColorOrder(int mainColorMode, int rgbwOrder)
		{
            int i, num, tail;

			this.mainColorMode = mainColorMode;
			this.rgbwOrder = rgbwOrder;
			

            // 初始化列映射表
            for (i = 0; i < 512; i++)
            {
                manualColorList[i] = Convert.ToByte(0xFF);
            } 
            
            // 根据颜色模式赋值
			if (mainColorMode == 3)
            {
				num = channel / 3;
				tail = channel % 3;
                switch (rgbwOrder)
                {
                    case 0:		// 规则颜色为RGB
                        for (i = 0; i < num; i++)
                        {
                            manualColorList[6 * i] = Convert.ToByte(i);
                            manualColorList[6 * i + 1] = 0;
                            manualColorList[6 * i + 2] = Convert.ToByte(i);
                            manualColorList[6 * i + 3] = 1;
                            manualColorList[6 * i + 4] = Convert.ToByte(i);
                            manualColorList[6 * i + 5] = 2;
                        }
						if (tail == 1)
						{
							manualColorList[6 * i] = Convert.ToByte(i);
							manualColorList[6 * i + 1] = 0;
						}
						else if (tail == 2)
						{
							manualColorList[6 * i] = Convert.ToByte(i);
							manualColorList[6 * i + 1] = 0;
							manualColorList[6 * i + 2] = Convert.ToByte(i);
							manualColorList[6 * i + 3] = 1;
						}
                        break;
                    case 1:		// 规则颜色为RBG
                        for (i = 0; i < num; i++)
                        {
                            manualColorList[6 * i] = Convert.ToByte(i);
                            manualColorList[6 * i + 1] = 0;
                            manualColorList[6 * i + 2] = Convert.ToByte(i);
                            manualColorList[6 * i + 3] = 2;
                            manualColorList[6 * i + 4] = Convert.ToByte(i);
                            manualColorList[6 * i + 5] = 1;
                        }
						if (tail == 1)
						{
							manualColorList[6 * i] = Convert.ToByte(i);
							manualColorList[6 * i + 1] = 0;
						}
						else if (tail == 2)
						{
							manualColorList[6 * i] = Convert.ToByte(i);
							manualColorList[6 * i + 1] = 0;
							manualColorList[6 * i + 2] = Convert.ToByte(i);
							manualColorList[6 * i + 3] = 2;
						}
                        break;
                    case 2:		// 规则颜色为BGR
                        for (i = 0; i < num; i++)
                        {
                            manualColorList[6 * i] = Convert.ToByte(i);
                            manualColorList[6 * i + 1] = 2;
                            manualColorList[6 * i + 2] = Convert.ToByte(i);
                            manualColorList[6 * i + 3] = 1;
                            manualColorList[6 * i + 4] = Convert.ToByte(i);
                            manualColorList[6 * i + 5] = 0;
                        }
						if (tail == 1)
						{
							manualColorList[6 * i] = Convert.ToByte(i);
							manualColorList[6 * i + 1] = 2;
						}
						else if (tail == 2)
						{
							manualColorList[6 * i] = Convert.ToByte(i);
							manualColorList[6 * i + 1] = 2;
							manualColorList[6 * i + 2] = Convert.ToByte(i);
							manualColorList[6 * i + 3] = 1;
						}
                        break;
                    case 3:		// 规则颜色为BRG
                        for (i = 0; i < num; i++)
                        {
                            manualColorList[6 * i] = Convert.ToByte(i);
                            manualColorList[6 * i + 1] = 2;
                            manualColorList[6 * i + 2] = Convert.ToByte(i);
                            manualColorList[6 * i + 3] = 0;
                            manualColorList[6 * i + 4] = Convert.ToByte(i);
                            manualColorList[6 * i + 5] = 1;
                        }
						if (tail == 1)
						{
							manualColorList[6 * i] = Convert.ToByte(i);
							manualColorList[6 * i + 1] = 2;
						}
						else if (tail == 2)
						{
							manualColorList[6 * i] = Convert.ToByte(i);
							manualColorList[6 * i + 1] = 2;
							manualColorList[6 * i + 2] = Convert.ToByte(i);
							manualColorList[6 * i + 3] = 0;
						}
                        break;
                    case 4:		// 规则颜色为GRB
                        for (i = 0; i < num; i++)
                        {
                            manualColorList[6 * i] = Convert.ToByte(i);
                            manualColorList[6 * i + 1] = 1;
                            manualColorList[6 * i + 2] = Convert.ToByte(i);
                            manualColorList[6 * i + 3] = 0;
                            manualColorList[6 * i + 4] = Convert.ToByte(i);
                            manualColorList[6 * i + 5] = 2;
                        }
						if (tail == 1)
						{
							manualColorList[6 * i] = Convert.ToByte(i);
							manualColorList[6 * i + 1] = 1;
						}
						else if (tail == 2)
						{
							manualColorList[6 * i] = Convert.ToByte(i);
							manualColorList[6 * i + 1] = 1;
							manualColorList[6 * i + 2] = Convert.ToByte(i);
							manualColorList[6 * i + 3] = 0;
						}
                        break;
                    case 5:		// 规则颜色为GBR
                        for (i = 0; i < num; i++)
                        {
                            manualColorList[6 * i] = Convert.ToByte(i);
                            manualColorList[6 * i + 1] = 1;
                            manualColorList[6 * i + 2] = Convert.ToByte(i);
                            manualColorList[6 * i + 3] = 2;
                            manualColorList[6 * i + 4] = Convert.ToByte(i);
                            manualColorList[6 * i + 5] = 0;
                        }
						if (tail == 1)
						{
							manualColorList[6 * i] = Convert.ToByte(i);
							manualColorList[6 * i + 1] = 1;
						}
						else if (tail == 2)
						{
							manualColorList[6 * i] = Convert.ToByte(i);
							manualColorList[6 * i + 1] = 1;
							manualColorList[6 * i + 2] = Convert.ToByte(i);
							manualColorList[6 * i + 3] = 2;
						}
                        break;
                    default:
                        break;
                }
            }
			else if (mainColorMode == 4)
			{
				num = channel / 4;
				tail = channel % 4;
				switch (rgbwOrder)
				{
					case 0:		// 规则颜色为RGBW
					case 6:		// 规则颜色为RGBW
						for (i = 0; i < num; i++)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 0;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 1;
							manualColorList[8 * i + 4] = Convert.ToByte(i);
							manualColorList[8 * i + 5] = 2;
							manualColorList[8 * i + 6] = Convert.ToByte(i);
							manualColorList[8 * i + 7] = 4;
						}
						if (tail == 1)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 0;
						}
						else if (tail == 2)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 0;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 1;
						}
						else if (tail == 3)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 0;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 1;
							manualColorList[8 * i + 4] = Convert.ToByte(i);
							manualColorList[8 * i + 5] = 2;
						}
						break;
					case 1:		// 规则颜色为RBGW
						for (i = 0; i < num; i++)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 0;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 2;
							manualColorList[8 * i + 4] = Convert.ToByte(i);
							manualColorList[8 * i + 5] = 1;
							manualColorList[8 * i + 6] = Convert.ToByte(i);
							manualColorList[8 * i + 7] = 4;
						}
						if (tail == 1)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 0;
						}
						else if (tail == 2)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 0;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 2;
						}
						else if (tail == 3)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 0;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 2;
							manualColorList[8 * i + 4] = Convert.ToByte(i);
							manualColorList[8 * i + 5] = 1;
						}
						break;
					case 2:		// 规则颜色为BGRW
						for (i = 0; i < num; i++)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 2;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 1;
							manualColorList[8 * i + 4] = Convert.ToByte(i);
							manualColorList[8 * i + 5] = 0;
							manualColorList[8 * i + 6] = Convert.ToByte(i);
							manualColorList[8 * i + 7] = 4;
						}
						if (tail == 1)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 2;
						}
						else if (tail == 2)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 2;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 1;
						}
						else if (tail == 3)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 2;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 1;
							manualColorList[8 * i + 4] = Convert.ToByte(i);
							manualColorList[8 * i + 5] = 0;
						}
						break;
					case 3:		// 规则颜色为BRGW
						for (i = 0; i < num; i++)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 2;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 0;
							manualColorList[8 * i + 4] = Convert.ToByte(i);
							manualColorList[8 * i + 5] = 1;
							manualColorList[8 * i + 6] = Convert.ToByte(i);
							manualColorList[8 * i + 7] = 4;
						}
						if (tail == 1)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 2;
						}
						else if (tail == 2)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 2;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 0;
						}
						else if (tail == 3)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 2;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 0;
							manualColorList[8 * i + 4] = Convert.ToByte(i);
							manualColorList[8 * i + 5] = 1;
						}
						break;
					case 4:		// 规则颜色为GRBW
						for (i = 0; i < num; i++)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 1;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 0;
							manualColorList[8 * i + 4] = Convert.ToByte(i);
							manualColorList[8 * i + 5] = 2;
							manualColorList[8 * i + 6] = Convert.ToByte(i);
							manualColorList[8 * i + 7] = 4;
						}
						if (tail == 1)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 1;
						}
						else if (tail == 2)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 1;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 0;
						}
						else if (tail == 3)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 1;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 0;
							manualColorList[8 * i + 4] = Convert.ToByte(i);
							manualColorList[8 * i + 5] = 2;
						}
						break;
					case 5:		// 规则颜色为GBRW
						for (i = 0; i < num; i++)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 1;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 2;
							manualColorList[8 * i + 4] = Convert.ToByte(i);
							manualColorList[8 * i + 5] = 0;
							manualColorList[8 * i + 6] = Convert.ToByte(i);
							manualColorList[8 * i + 7] = 4;
						}
						if (tail == 1)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 1;
						}
						else if (tail == 2)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 1;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 2;
						}
						else if (tail == 3)
						{
							manualColorList[8 * i] = Convert.ToByte(i);
							manualColorList[8 * i + 1] = 1;
							manualColorList[8 * i + 2] = Convert.ToByte(i);
							manualColorList[8 * i + 3] = 2;
							manualColorList[8 * i + 4] = Convert.ToByte(i);
							manualColorList[8 * i + 5] = 0;
						}
						break;
					default:
						break;
				}
			}
		}

		public byte[] GetManualColorArray()
		{
			return manualColorList.ToArray();
		}

		public void GetManualColorArray(byte[] byteData)
		{
			for (int i = 0; i < manualColorList.Count; i++)
			{
				byteData[i] = manualColorList[i];
			}
		}

		public void SetManualColorArray(byte[] byteData)
		{
            int lll, i;

            //判断映射表长度
			if (byteData.Length > 512)
			{
				lll = 512;
			}
			else
			{
				lll = byteData.Length;
			}

            for (i = 0; i < lll; i++)
			{
				manualColorList[i] = byteData[i];
			}

            for (i = lll; i < 512; i++)
            {
                manualColorList[i] = Convert.ToByte(0xFF);
            }
            //colorOrderMode = 1;
		}

		public void GetDxfData(int[] value)
		{
			if (value.Length != 4)
			{
				return;
			}

			for (int i = 0; i < 4; i++)
			{
				value[i] = dxfData[i];
			}
		}

		public void SetDxfData(int[] value)
		{
			if (value.Length != 4)
			{
				return;
			}

			for (int i = 0; i < 4; i++)
			{
				dxfData[i] = value[i];
			}
		}

		public void SetSelectedChipMode(int mode)
		{
			if (mode == 3 || mode == 4)
			{
				mainColorMode = mode;
			}
			else
			{
				mainColorMode = 3;
			}
		}

		public void SetSysControlMode(int value)
		{
			sysControlMode = value;
		}

		#endregion

		#region 辅助函数

		#region CRC32 Table

		ulong[] m_CRC32_Table = {
	    0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
	    0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
	    0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
	    0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
	    0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
	    0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
	    0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
	    0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
	    0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
	    0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
	    0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
	    0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
	    0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
	    0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
	    0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
	    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
	    0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
	    0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
	    0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
	    0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
	    0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
	    0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
	    0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
	    0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
	    0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
	    0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
	    0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
	    0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
	    0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
	    0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
	    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
	    0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
    };

		#endregion

		// 获取当前 exe 路径
		private string GetAppPath()
		{
			return zqConfig.GetAppPath();
		}

		// Bytes 转 Chars
		public void Bytes2Chars(List<byte> byteData, int offset, int length, char[] charData)
		{
			for (int i = 0; i < length; i++)
			{
				int value = Convert.ToInt32(byteData[i + offset]);
				charData[i] = Convert.ToChar(value);
			}
		}

		// 生成 CRC32 校验码
		private ulong GetCRC32(byte[] input, ulong size)
		{
			ulong result = 0xffffffff;
			ulong length = 0;
			length = size;
			int i = 4;
			while (length-- != 0)
			{
				result = (result >> 8) ^ m_CRC32_Table[(result & 0xFF) ^ input[i++]];
			}
			return result ^ 0xffffffff;
		}

		// CRC校验
		private bool IsOkCheckSum(byte[] data, ulong dataLength, ulong crcValue)
		{
			if (GetCRC32(data, dataLength) == crcValue)
			{
				return true;
			}
			else
			{
				return false;
			}
		}

		#endregion
	}
}
